# -*-coding:utf-8 -*-
#!/usr/bin/env python
#function: 字符提取(水平垂直投影法）
#input:预处理后的二值化图像
#output:字符提取结果（以png格式保存与当前目录get文件夹）和个十位压线标志位touchline1和小数位压线标志touchline0

import cv2
import numpy as np
import os

#定位十位个位数字
def loc1(src):
    left1=right1=left2=right2=bottom0=top0=0
    #定位水位十位个位数字左右边界
    col_sum = src.sum(axis=0) #列和


    for i in range(len(col_sum)):
        if (col_sum[i]!=0 and left1==0):
            left1=i
        elif(left1!=0 and col_sum[i]==0 and right1==0):
            right1=i
        elif(right1!=0 and col_sum[i]!=0 and left2==0):
            left2=i
        elif(left2!=0 and col_sum[i]==0 and right2==0):
            right2=i
            break

    col_slice1 = src[:,left1-2:right1+2]  #留2像素边缘
    col_slice2 = src[:,left2-2:right2+2]
    cv2.imwrite('process\\col_slice1.png',col_slice1)#中间过程图像
    cv2.imwrite('process\\col_slice2.png',col_slice2)

    #定位水位十位个位数字上下边界
    row_sum = col_slice1.sum(axis=1) #列片的行和
    a = list(range(len(row_sum))) 
    a.reverse()   #创建一个逆序索引
    for i in a:
        if(row_sum[i]!=0 and bottom0==0):
            bottom0=i
        else:
            if(row_sum[i]==0 and bottom0!=0):
                top0=i
                break

    #确定截取字符尺寸即边缘裕度
    width1 = right1-left1
    width2 = right2-left2    
    hight = bottom0-top0
    size = max(width1, width2, hight)
    row_margin1 = int((size-width1)/2)-2
    row_margin2 = int((size-width2)/2)+1
    col_margin1 = int((size-hight)/2)-2   
    col_margin2 = int((size-hight)/2)+1
    
    slice1 = src[top0-col_margin1:bottom0+col_margin1,left1-row_margin1:right1+row_margin1] #留2像素边缘
    slice2 = src[top0-col_margin2:bottom0+col_margin2,left2-row_margin2:right2+row_margin2]

    #显示并保存字符提取结果
    #cv2.imshow('slice1',slice1)
    #cv2.imshow('slice2',slice2)
    cv2.imwrite('get\\slice1.png',slice1)
    cv2.imwrite('get\\slice2.png',slice2)
    return left1,right1, left2,right2,bottom0,top0


#定位小数位数字
def loc2(src):
    left=right=bottom=top=0 
    #定位水位线数字上下边界
    row_sum=src.sum(axis=1)  #行和
    a = list(range(len(row_sum)))
    a.reverse() #长度为row_sum的逆序序列，...2,1,0，用于循环

    bottom=top=0 

    for i in a:
        if(row_sum[i]!=0 and bottom==0):
            bottom=i
        else:
            if(row_sum[i]==0 and bottom!=0):
                top=i
                break

    row_slice = src[top-2:bottom+2,:]  #水平切片，留2像素边缘
    cv2.imwrite('process\\row_slice.png',row_slice)

    #定位水位线数字左右边界
    col_sum = row_slice.sum(axis=0) #列和
    a = list(range(len(col_sum)))
    a.reverse()

    for i in a:
        if(col_sum[i]!=0 and right==0):
            right=i
        else:
            if(col_sum[i]==0 and right!=0):
                left=i
                break

    #确定截取字符尺寸即边缘裕度
    width = right-left   
    hight = bottom-top
    size = max(width, hight)
    row_margin = int((size-width)/2)+1
    col_margin = int((size-hight)/2)+1
    slice3 = src[top-col_margin:bottom+col_margin,left-row_margin:right+row_margin] #从水平切片提取字符


    #cv2.imshow('slice3',slice3)
    cv2.imwrite('get\\slice3.png',slice3)
    return left,right,bottom,top

#压线检测：字符高度不及宽度2/3或者小于特定阈值
def touch_detect(left,right,bottom,top):
    touchline = 0
    width = right -left
    hight = bottom - top
    
    if hight<width*(0.9) or hight<12:
        touchline = 1
        print("touch line!\n")
    return touchline


#主函数
def char_loc(src, detail=0):
    left1=right1=left2=right2=bottom0=top0=0   #个位十位数字边界
    left=right=bottom=top=0 #小数位数字边界
    touchline = 0 #十个位、小数位压线检测标志位


    #获取小数位边界
    left,right,bottom,top = loc2(src)
    touchline = touch_detect(left,right,bottom,top) #压线检测，只检测小数位即可，因为十个位压线时，小数位必压线
    if touchline==1:
        src = src[:top-2,:]   
        left,right,bottom,top = loc2(src)            

    #获取十位个位边界
    left1,right1, left2,right2,bottom0,top0 = loc1(src)
     
    
    if detail==1:  #显示字符提取过程图细节标志位

        print('---------characters localization:-----------\n')
        #打印字符位置
        print('character1:')
        print('left1: %d, right1: %d, bottom1: %d, top1: %d\n' %(left1,right1, bottom0,top0))
        print('character2:')
        print('left2: %d, right2: %d, bottom2: %d, top2: %d\n' %(left2,right2, bottom0,top0))
        if 1:
            print('character3:')
            print('left:%d, right:%d, bottom:%d, top:%d\n'%(left,right,bottom,top))             

    return touchline
